package com.ht.oss.controller;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.ht.oss.ResData;
import com.ht.oss.config.BucketsConfig;
import com.ht.oss.service.OssService;
import com.ht.oss.utils.TypeCheckUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

@RestController
@RequestMapping("/api")
public class OssController {

    @Autowired
    private BucketsConfig bucketsConfig;

    @Autowired
    private OssService ossService;

    @PostMapping("/img")
    public ResData<String> upLoadImage(@RequestParam("file") MultipartFile file) {
        try (
                InputStream in = file.getInputStream();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ) {
            IoUtil.copy(in, bos);
            byte[] byteArray = bos.toByteArray();
            String type = FileTypeUtil.getType(new ByteArrayInputStream(byteArray));
            if (TypeCheckUtil.isImage(type)) {
                String md5 = ossService.upload(bos.toByteArray(), bucketsConfig.getImageBucket(), type);
                return ResData.success(null, md5);
            } else {
                return ResData.fail("文件异常，请重新选择文件");
            }
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
    }

    @GetMapping("/img/{md5}")
    public void downloadImage(@PathVariable("md5") String md5, HttpServletResponse response) {
        File file = ossService.download(bucketsConfig.getImageBucket(), md5);
        try (
                InputStream is = file == null ? null : Files.newInputStream(file.toPath());
                ServletOutputStream os = response.getOutputStream();
        ) {
            if (is == null) {
                response.setContentType(ContentType.JSON.getValue());
                os.write(JSONUtil.toJsonStr(ResData.<Void>fail("图片不存在，请稍后再试")).getBytes(StandardCharsets.UTF_8));
                return;
            }
            response.setContentType("image/" + FileUtil.getSuffix(file));
            IoUtil.copy(is, os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @DeleteMapping("/img/{md5}")
    public ResData<String> removeImage(@PathVariable("md5") String md5) {
        if (ossService.deleteFile(bucketsConfig.getImageBucket(), md5)) {
            return ResData.success();
        } else {
            return ResData.fail("删除失败，请重试");
        }
    }

    @PostMapping("/")
    public ResData<String> upLoad(@RequestParam("file") MultipartFile file) {
        try (
                InputStream in = file.getInputStream();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ) {
            IoUtil.copy(in, bos);
            byte[] byteArray = bos.toByteArray();
            String md5 = ossService.upload(byteArray);
            return ResData.success(null, md5);
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
    }

    @GetMapping("/{md5}")
    public void download(@PathVariable("md5") String md5, HttpServletResponse response) {
        File file = ossService.download(bucketsConfig.getObjBucket(), md5);
        try (
                InputStream is = file == null ? null : Files.newInputStream(file.toPath());
                ServletOutputStream os = response.getOutputStream();
        ) {
            if (is == null) {
                response.setContentType(ContentType.JSON.getValue());
                os.write(JSONUtil.toJsonStr(ResData.<Void>fail("文件不存在，请稍后再试")).getBytes(StandardCharsets.UTF_8));
                return;
            }
            IoUtil.copy(is, os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @DeleteMapping("/{md5}")
    public ResData<String> remove(@PathVariable("md5") String md5) {
        if (ossService.deleteFile(bucketsConfig.getObjBucket(), md5)) {
            return ResData.success();
        } else {
            return ResData.fail("删除失败，请重试");
        }
    }
}
